﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Web.Security;
using System.Web;
using RC.ControlAcceso.BaseDatos;
using RC.ControlAcceso.BaseDatos.GestionHorariaTableAdapters;

namespace RC.ControlAcceso.ObjetosNegocio
{
    /// <summary>
    /// Clase de propiedades derivadas y presentacion
    /// </summary>
    public partial class CA2Usuario
    {
        public string ApellidoYNombre
        {
            get
            {
                return Apellido + ", " + Nombre;
            }
        }
        public string FechaNacimientoString
        {
            get
            {
                if (FechaNacimiento <= CA2Parametros.FechaMinima)
                    return "";
                return FechaNacimiento.ToString("dd/MM/yyyy");
            }
            set
            {
                DateTime _fecha ;
                if ((value == null)
                    || (value == "")
                    || (DateTime.TryParse(value, out _fecha) == false))
                    FechaNacimiento = CA2Parametros.FechaMinima;
                else
                    FechaNacimiento = _fecha;
            }
        }
        public System.Drawing.Color EstaBloqueadoStringColor
        {
            get
            {
                if (EstaBloqueado == true)
                    return CA2Parametros.ColorInactivo;
                else
                    return CA2Parametros.ColorActivo;
            }
        }
        public string EstaBloqueadoString
        {
            get
            {
                if (EstaBloqueado == true)
                    return "Bloqueado";
                else
                    return "Activo";
            }
        }
    }
    /// <summary>
    /// Solo contiene propiedades y métodos que acceden a el framework de seguridad
    /// </summary>
    public partial class CA2Usuario
    {   
        private string _email;
        public string UsuarioId
        {
            get
            {
                return _UsuarioId;
            }
            set
            {
                _UsuarioId = value;
            }
        }
        public string Contrasena
        {
            get
            {
                return _Contrasena;
            }
            set
            {
                _Contrasena = value;
            }
        }
        public string Email
        {
            get
            {   
                MembershipUser _usuario = Membership.GetUser(UsuarioId);
                if (_usuario == null)
                    _email = "";
                else
                    _email = _usuario.Email;

                return _email;
            }
            set
            {
                _email = value;
            }

        }
        public bool EstaBloqueado
        {
            get
            {
                MembershipUser _usuario = Membership.GetUser(UsuarioId);
                if (_usuario == null)
                    return false;

                return ((!_usuario.IsApproved) || _usuario.IsLockedOut);
            }
        }
        public string[] RolesAsignados
        {
            get
            {
                return Roles.GetRolesForUser(UsuarioId);
            }
            set
            {
                _Roles = value;
            }
        }
        public string[] TodosLosRoles
        {
            get
            {
                return SeguridadObtenerTodosLosRoles();
            }
        }

        /// <summary>
        /// Bloquea la cuenta del usuario para que no pueda ingresar al sistema
        /// </summary>
        public static void SeguridadBloquearUsuario(string pUsuarioId)
        {
            MembershipUser _usuario = Membership.GetUser(pUsuarioId);
            if (_usuario == null)
                return;

            _usuario.IsApproved = false;
            Membership.UpdateUser(_usuario);
        }
        public bool SeguridadSePuedeBloquearUsuario
        {
            get
            {
                MembershipUser _usuario = Membership.GetUser(UsuarioId);
                if (_usuario == null)
                    return false;

                if (_usuario.IsApproved == true)
                    return true;
                else
                    return false;
            }
        }
        /// <summary>
        /// Desbloquea la cuenta del usuario para que pueda ingresar al sistema
        /// </summary>
        public static void SeguridadDesbloquearUsuario(string pUsuarioId)
        {
            MembershipUser _usuario = Membership.GetUser(pUsuarioId);
            if (_usuario == null)
                return;

            _usuario.UnlockUser();
            _usuario.IsApproved = true;
            Membership.UpdateUser(_usuario);
        }
        public bool SeguridadSePuedeDesbloquearUsuario
        {
            get
            {
                MembershipUser _usuario = Membership.GetUser(UsuarioId);
                if (_usuario == null)
                    return false;

                if (_usuario.IsApproved == false)
                    return true;
                else
                    return false;
            }
        }
        public static bool SeguridadCrearUsuario(string pUsuarioId, string pContrasena, string pEmail)
        {

            //antes de crear pruebo de crear el usuario en el framework de seguridad
           MembershipCreateStatus _estadoCreacion;
            Membership.CreateUser(pUsuarioId, pContrasena, pEmail, "asdffdsa", "asdffdsa", true, out _estadoCreacion);

            SeguridadProcesarResultadoOperacion(_estadoCreacion);

            return true;
        }
        public static bool SeguridadCambiarContrasena(string pUsuarioId, string pContrasena)
        {
            MembershipUser _usuario = Membership.GetUser(pUsuarioId);
            if (_usuario == null)
                return false;

            _usuario.ChangePassword(_usuario.ResetPassword(), pContrasena);
            return true;
            
        }
        /// <summary>
        /// Si hay algun error lo muestra a travez de una excepcion
        /// </summary>
        private static void SeguridadProcesarResultadoOperacion(MembershipCreateStatus pEstadoCreacion)
        {
            switch (pEstadoCreacion)
            {
                case MembershipCreateStatus.Success:
                    break;
                case MembershipCreateStatus.DuplicateUserName:
                    throw new ArgumentException("Ya existe un usuario con el nombre ingresado.");
                //break;
                case MembershipCreateStatus.DuplicateEmail:
                    throw new ArgumentException("Ya existe un usuario con la dirección de correo especificada.");
                //break;
                case MembershipCreateStatus.InvalidEmail:
                    throw new ArgumentException("La dirección de correo ingresada es incorrecta.");
                //break;
                case MembershipCreateStatus.InvalidAnswer:
                    throw new ArgumentException("La respuesta de pregunta secreta es inválida.");
                //break;
                case MembershipCreateStatus.InvalidPassword:
                    throw new ArgumentException("La contraseña ingresada es inválida. Debe contener 7 caracteres y al menos un caracter no alfanumérico.");
                //break;
                default:
                    throw new ArgumentException("Ocurrió un error desconocido; el usuario NO fué creado.");
                //break;
            }
        }
        /// <summary>
        /// Asigna los roles establecidos en el parametro, si existen otros roles anteriores, los quita.
        /// </summary>
        /// <param name="pUsuario"></param>
        /// <param name="pRoles"></param>
        public static void SeguridadAsignarUsuarioARoles(string pUsuario, string[] pRoles)
        {
            //si tengo roles asignados, los quito
            if(Roles.GetRolesForUser(pUsuario).Length > 0)
                Roles.RemoveUserFromRoles(pUsuario, Roles.GetRolesForUser(pUsuario));
            
            if ((pRoles == null)
                || (pRoles.Length == 0)
                || (pRoles[0] == ""))
                return;
            
            Roles.AddUserToRoles(pUsuario, pRoles);
        }
        /// <summary>
        /// Obtiene todos los roles existentes
        /// </summary>
        /// <returns></returns>
        public static string[] SeguridadObtenerTodosLosRoles()
        {
            return Roles.GetAllRoles();
        }
        /// <summary>
        /// Verifica si el usuario existe 
        /// </summary>
        /// <param name="pUsuarioID"></param>
        /// <param name="pRol"></param>
        /// <param name="pContrasena"></param>
        /// <param name="pEmail"></param>
        /// <returns></returns>
        public static bool SeguridadUsuarioIdExiste(string pUsuarioID)
        {
            MembershipUser _usuario = Membership.GetUser(pUsuarioID);
            if (_usuario != null)
                return true;
            else
                return false;
        }
        /// <summary>
        /// Elimina el usuario
        /// </summary>
        /// <param name="pUsuarioId"></param>
        public static void SeguridadEliminarUsuario(string pUsuarioId)
        {
            Membership.DeleteUser(pUsuarioId);
        }
    }

    public partial class CA2Usuario
    {
        #region Atributos
        protected int _ID;
        protected string _Nombre;
        protected string _Apellido;
        protected string _DocumentoTipo;
        protected string _DocumentoNumero;
        protected string _Pais;
        protected string _Provincia;
        protected string _Localidad;
        protected string _Domicilio;
        protected string _Telefono;
        protected string _Celular;
        protected DateTime _FechaNacimiento;

        protected string _UsuarioId;
        protected string _Contrasena;
        protected bool _Activo;
        protected string[] _Roles;

        #endregion

        #region Propiedades
        public int ID
        {
            get
            {
                return _ID;
            }
            set
            {
                _ID = value;
            }
        }
        public string Nombre
        {
            get
            {
                return _Nombre;
            }
            set
            {
                _Nombre = value;
            }
        }
        public string Apellido
        {
            get
            {
                return _Apellido;
            }
            set
            {
                _Apellido = value;
            }
        }
        public string DocumentoTipo
        {
            get
            {
                return _DocumentoTipo;
            }
            set
            {
                _DocumentoTipo = value;
            }
        }
        public string DocumentoNumero
        {
            get
            {
                return _DocumentoNumero;
            }
            set
            {
                _DocumentoNumero = value;
            }
        }
        public string Pais
        {
            get
            {
                return _Pais;
            }
            set
            {
                _Pais = value;
            }
        }
        public string Provincia
        {
            get
            {
                return _Provincia;
            }
            set
            {
                _Provincia = value;
            }
        }
        public string Localidad
        {
            get
            {
                return _Localidad;
            }
            set
            {
                _Localidad = value;
            }
        }
        public string Domicilio
        {
            get
            {
                return _Domicilio;
            }
            set
            {
                _Domicilio = value;
            }
        }
        public string Telefono
        {
            get
            {
                return _Telefono;
            }
            set
            {
                _Telefono = value;
            }
        }
        public string Celular
        {
            get
            {
                return _Celular;
            }
            set
            {
                _Celular = value;
            }
        }
        public DateTime FechaNacimiento
        {
            get
            {
                return _FechaNacimiento;
            }
            set
            {
                _FechaNacimiento = value;
            }
        }
        //Propiedades derivadas

        #endregion

        #region Interfase DAL
        //objeto de la capa DAL

        private static CAUsuarioTableAdapter _UsuarioAD;
        protected static CAUsuarioTableAdapter Adaptador
        {
            get
            {
                if (_UsuarioAD == null)
                    _UsuarioAD = new CAUsuarioTableAdapter();

                return _UsuarioAD;
            }
        }
        public static CA2Usuario ObtenerPorID(int pID)
        {
            CA2Usuario _Usuario = null;

            GestionHoraria.CAUsuarioDataTable _dt;

            // obtengo el elemento por ID
            CAUsuarioTableAdapter _adaptador = new CAUsuarioTableAdapter(); // lo creo aca por que este es un metodo estatico
            _dt = _adaptador.ObtenerUsuarioPorId(pID);

            // si tiene algo,
            if (_dt.Rows.Count > 0)
                _Usuario = AsignarRowAObjeto((GestionHoraria.CAUsuarioRow)_dt.Rows[0]);

            return _Usuario;
        }
        public static CA2Usuario ObtenerPorUsuarioID(string pUsuarioID)
        {
            CA2Usuario _Usuario = null;

            GestionHoraria.CAUsuarioDataTable _dt;

            // obtengo el elemento por ID
            CAUsuarioTableAdapter _adaptador = new CAUsuarioTableAdapter(); // lo creo aca por que este es un metodo estatico
            _dt = _adaptador.ObtenerUsuarioPorUsuarioId(pUsuarioID);

            // si tiene algo,
            if (_dt.Rows.Count > 0)
                _Usuario = AsignarRowAObjeto((GestionHoraria.CAUsuarioRow)_dt.Rows[0]);

            return _Usuario;
        }
        protected static CA2Usuario AsignarRowAObjeto(GestionHoraria.CAUsuarioRow pRow)
        {
            CA2Usuario _Usuario = null;
            if (pRow != null)
            {
                _Usuario = new CA2Usuario();
                _Usuario.ID = pRow.ID;
                _Usuario.Nombre = pRow.Nombre;
                _Usuario.Apellido = pRow.Apellido;
                _Usuario.DocumentoTipo = pRow.DocumentoTipo;
                _Usuario.DocumentoNumero = pRow.DocumentoNumero;
                _Usuario.Pais = pRow.Pais;
                _Usuario.Provincia = pRow.Provincia;
                _Usuario.Localidad = pRow.Localidad;
                _Usuario.Domicilio = pRow.Domicilio;
                _Usuario.Telefono = pRow.Telefono;
                _Usuario.Celular = pRow.Celular;
                _Usuario.FechaNacimiento = pRow.FechaNacimiento;
                _Usuario.UsuarioId = pRow.UsuarioId;
            }
            return _Usuario;
        }
        public static CA2Usuario Insertar(string pNombre, string pApellido, string pDocumentoTipo, string pDocumentoNumero, string pPais, string pProvincia, string pLocalidad, string pDomicilio, string pTelefono, string pCelular, DateTime pFechaNacimiento, string pUsuarioId, string pContrasena, string  pEmail, string[] pRoles)
        {
            ///*******************************************************************************
            ///Agregar para validar el usaurio si esta disponible y darlo de alta al framework
            ///*******************************************************************************
            ///
            if (SeguridadUsuarioIdExiste(pUsuarioId) == true)
                throw new ArgumentException("El usuario ya existe");

            SeguridadCrearUsuario(pUsuarioId, pContrasena, pEmail);
            SeguridadAsignarUsuarioARoles(pUsuarioId, pRoles);

            int _IdUsuarioNueva = int.Parse(Adaptador.Insertar(pNombre, pApellido, pDocumentoNumero, pDocumentoTipo, pPais, pProvincia, pLocalidad, pDomicilio, pTelefono, pCelular, pFechaNacimiento, pUsuarioId).ToString());
            CA2Usuario _Usuario = CA2Usuario.CrearUsuario(_IdUsuarioNueva);
            return _Usuario;
        }
        public static bool Actualizar(int pID, string pNombre, string pApellido, string pDocumentoTipo, string pDocumentoNumero, string pPais, string pProvincia, string pLocalidad, string pDomicilio, string pTelefono, string pCelular, DateTime pFechaNacimiento, string pEmail, string[] pRoles, string pUsuarioId)
        {
            if (pID == 0)
                return false;
            
            // Actualizo el email en el framework de seguridad
            MembershipUser _usuario = Membership.GetUser(pUsuarioId);
            _usuario.Email = pEmail;
            Membership.UpdateUser(_usuario);

            CA2Usuario.SeguridadAsignarUsuarioARoles(pUsuarioId, pRoles);

            if (0 < Adaptador.Actualizar(pNombre, pApellido, pDocumentoNumero, pDocumentoTipo, pPais, pProvincia, pLocalidad, pDomicilio, pTelefono, pCelular, pFechaNacimiento, pUsuarioId, pID))
                return true;
            else
                return false;
        }
        /// <summary>
        /// El resultado indica si el registro se elimino o no.
        /// </summary>
        /// <param name="pId"></param>
        /// <returns>Indica si el registro se elimino o no.</returns>
        public static bool Eliminar(int pId)
        {
            CA2Usuario _usuario = CA2Usuario.ObtenerPorID(pId);

            if (Adaptador.Eliminar(pId) == 0)
                return false;
            else
            {
                SeguridadEliminarUsuario(_usuario.UsuarioId);
                return true;
            }
        }
        public static CA2UsuarioColeccion ObtenerTodosLosUsuarios()
        {
            GestionHoraria.CAUsuarioDataTable _dt;

            CAUsuarioTableAdapter _adaptador = new CAUsuarioTableAdapter(); // lo creo aca por que este es un metodo estatico
            _dt = _adaptador.ObtenerTodosLosUsuarios();

            return AsignarUsuarioTableAdapterAUsuarioColeccion(_dt);

        }
        /// <summary>
        /// Obtiene todos los usuarios que tienen un determinado valor.
        /// Si el paramerto pValor es nulo o "", te devuelven todos los usuarios
        /// </summary>
        /// <param name="pValor">Si es "" o nulo, se obtienen todos los usuarios.</param>
        /// <returns></returns>
        public static CA2UsuarioColeccion ObtenerUsuariosPorValor(string pValor)
        {
            //si el valor es vacio o "" , se devuelven todos los usuarios.
            if ((pValor == null)
                || (pValor == ""))
                return ObtenerTodosLosUsuarios();

            GestionHoraria.CAUsuarioDataTable _dt;

            CAUsuarioTableAdapter _adaptador = new CAUsuarioTableAdapter(); // lo creo aca por que este es un metodo estatico
            _dt = _adaptador.ObtenerPorValor(pValor);

            return AsignarUsuarioTableAdapterAUsuarioColeccion(_dt);

        }
        public static CA2UsuarioColeccion ObtenerUsuariosPorValor2(string pValor)
        {
            //si el valor es vacio o "" , se devuelven todos los usuarios.
            if ((pValor == null)
                || (pValor == ""))
                return ObtenerTodosLosUsuarios();

            GestionHoraria.CAUsuarioDataTable _dt;

            CAUsuarioTableAdapter _adaptador = new CAUsuarioTableAdapter(); // lo creo aca por que este es un metodo estatico
            _dt = _adaptador.ObtenerTodos();

            return AsignarUsuarioTableAdapterAUsuarioColeccion(_dt);

        }
        protected static CA2UsuarioColeccion AsignarUsuarioTableAdapterAUsuarioColeccion(GestionHoraria.CAUsuarioDataTable pDataTable)
        {
            CA2UsuarioColeccion _Usuarios = new CA2UsuarioColeccion();
            CA2Usuario _Usuario;

            if ((pDataTable != null)
                && (pDataTable.Rows.Count > 0))
            {
                foreach (GestionHoraria.CAUsuarioRow _row in pDataTable.Rows)
                {
                    _Usuario = AsignarRowAObjeto(_row);
                    if (_Usuario != null)
                        _Usuarios.Add(_Usuario);
                }
            }
            return _Usuarios;
        }
        public bool Actualizar()
        {
            //NOTA: utilizo _email en vez de EMail ya que EMail lo obtiene desde el membership y necesito el valor establecido a la propiedad para poder actualizar
            return Actualizar(ID, Nombre, Apellido, DocumentoTipo, DocumentoNumero, Pais, Provincia, Localidad, Domicilio, Telefono, Celular, FechaNacimiento, _email, _Roles, UsuarioId);
        }
        public CA2Usuario Insertar()
        {
            //NOTA: utilizo _email en vez de EMail ya que EMail lo obtiene desde el membership y necesito el valor establecido a la propiedad para poder insertar
            return Insertar(Nombre, Apellido, DocumentoTipo, DocumentoNumero, Pais, Provincia, Localidad, Domicilio, Telefono, Celular, FechaNacimiento, UsuarioId, Contrasena, _email, _Roles);
        }
        public void Eliminar()
        {
            Eliminar(ID);
        }
        #endregion

        #region Métodos
        public CA2Usuario()
        {
            AsignarValoresIniciales();
        }
        public void AsignarValoresIniciales()
        {
            ID = -1;
            Nombre = "";
            Apellido = "";
            DocumentoTipo = "DNI";
            DocumentoNumero = "";
            Pais = "";
            Provincia = "";
            Localidad = "";
            Domicilio = "";
            Telefono = "";
            Celular = "";
            FechaNacimiento = CA2Parametros.FechaMinima;
            UsuarioId = "";
        }
        public static CA2Usuario CrearUsuario()
        {
            CA2Usuario _Usuario = new CA2Usuario();
            return _Usuario;
        }
        /// <summary>
        /// El id de la Usuario es el mismo que el numero de Usuario(es el mismo campo)
        /// </summary>
        /// <param name="pID"></param>
        /// <returns></returns>
        public static CA2Usuario CrearUsuario(int pID)
        {
            CA2Usuario _Usuario = ObtenerPorID(pID);
            return _Usuario;
        }
        #endregion

        #region Metodos para datasource
        public void Actualizar(CA2Usuario pUsuario)
        {
            if (pUsuario != null)
                pUsuario.Actualizar();
        }
        public CA2Usuario Insertar(CA2Usuario pUsuario)
        {
            if (pUsuario != null)
                return pUsuario.Insertar();
            return null;
        }
        public void Eliminar(CA2Usuario pUsuario)
        {
            pUsuario.Eliminar();
            pUsuario = null;
        }
        #endregion
    }
    public class CA2UsuarioColeccion : System.Collections.CollectionBase
    {
        public void Add(CA2Usuario pUsuario)
        {
            this.List.Add(pUsuario);
        }
        public void AddUnico(CA2Usuario pUsuario)
        {
            foreach (CA2Usuario _Usuario in this)
                if (pUsuario.ID == _Usuario.ID)
                    return;
            this.List.Add(pUsuario);
        }
        public void Remove(int index)
        {
            if (index <= Count - 1 || index >= 0)
            {
                this.List.RemoveAt(index);
            }
            else
            {
                throw new System.ArgumentException("Fuera de rango", "original");
            }
        }
        public void Remove(CA2Usuario pUsuario)
        {
            for (int i = 0; i < this.Count; i++)
            {
                if (this[i].ID == pUsuario.ID)
                {
                    Remove(i);
                    return;
                }

            }
        }
        public CA2Usuario this[int index]
        {
            get { return ((CA2Usuario)(this.List[index])); }
            set { this.List[index] = value; }
        }
    }
}

